package xiaoa.java.netty;

import java.net.URI;

import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;
import java.util.concurrent.TimeUnit;

import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLEngine;

import io.netty.channel.ChannelPipeline;
import io.netty.handler.codec.http.HttpRequest;
import io.netty.handler.ssl.SslHandler;
import io.netty.handler.timeout.ReadTimeoutHandler;
import io.netty.handler.timeout.WriteTimeoutHandler;

/***
 * http请求头工具类
 * @author xiaoa
 * @date 2017年8月17日 下午9:36:44
 * @version V1.0
 *
 */
public class HttpHandlerUtils {
	
	
	private static Map<String , String>  defaultHandler = new TreeMap<>();
	
	static {
		defaultHandler.put("Accept-Language", "zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3");
//		defaultHandler.put("Accept-Encoding", "deflate, sdch");
		defaultHandler.put("Content-Type", "application/x-javascript;charset=UTF-8");
		defaultHandler.put("Connection", "Keep-Alive");
		defaultHandler.put("User-Agent", "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36");
		defaultHandler.put("Accept", "*/*");
		
	}
	
	/**
	 *http  等待数据超时 请求头
	 */
	public static  String  HTTP_SOCKET_TIMEOUT = "http.socket.timeout";
	
	/**
	 * 写入
	 */
	public static  String  HTTP_SOCKET_TIMEOUT_W = "http.socket.timeout_w";

	
	/**
	 * ssl加密在通道中的名字
	 */
	private static String SSL_HADLER_NAME = "https_ssl";
	
	/**
	 * 填充请求头
	 * @Title: doFill
	 * @param request
	 * @author xiaoa
	 */
	public static void doFill(HttpRequest request , Map<String, String> handlerMap){
		if (request == null){
		     return ;
		}
		
		// 填充host
		URI uri = URI.create(request.uri());

		
		Map<String , String>  handlerMapTemp = new HashMap<>();

		handlerMapTemp.put("Host", uri.getHost() + ":" + getPort(uri) );
		
		
		// 初始化默认参数
        for (String key : defaultHandler.keySet()){
			
			String value = defaultHandler.get(key);
			
			if (value == null || value.isEmpty()){
				continue;
			}
			
			handlerMapTemp.put(key, value);
		}

		// 设置自定义参数
		if (handlerMap != null && handlerMap.size() > 0){
			for (String key : handlerMap.keySet()){

				String value = handlerMap.get(key);

				if (value == null || value.isEmpty()){
					continue;
				}
				handlerMapTemp.put(key, value);
			}
		}
		// 设置到request
		if (handlerMapTemp != null && handlerMapTemp.size() > 0){
			
			for (String key : handlerMapTemp.keySet()){
				
				String value =  handlerMapTemp.get(key);
				
				if (value != null && !value.isEmpty()){
					
					request.headers().add(key,value);
				}
			}
		}

	}
	
	
	/**
	 * 移除头
	 * @Title: doRemoveHanlder
	 * @param name
	 * @param pipeline
	 * @throws Exception
	 * @author xiaoa
	 */
	public static void doRemoveHanlder(String name , ChannelPipeline  pipeline)throws Exception{
		
		if (pipeline.get(name) != null){
			pipeline.remove(name);
		}
	}
	

	/**
	 * 填充处理handel
	 * @param pipeline
	 * @param url
     */
	public static void doFillInitHander(ChannelPipeline  pipeline , HttpRequest  request, String url)throws Exception{


		if (url == null || url.isEmpty() || request == null || pipeline == null){
			throw  new RuntimeException("参数有误");
		}
		
		
		// 如果是https 协议  并且没有添加
		if (url.toLowerCase().startsWith("https") && pipeline.get(SSL_HADLER_NAME) == null){
		
		   SSLEngine ssl =  SSLContext.getDefault().createSSLEngine();
		   ssl.setUseClientMode(true);
		   
		   pipeline.addAfter(HttpClient.FIRST_HANDLE_NAME,SSL_HADLER_NAME , new SslHandler(ssl));
		   
		}

		
		// 设置连接超时时间
		String s_timeOut = request.headers().get(HTTP_SOCKET_TIMEOUT);
		
		if (s_timeOut != null && !s_timeOut.isEmpty()){
			Long  time = Long.valueOf(s_timeOut);
			
			ReadTimeoutHandler  timeOut =  (ReadTimeoutHandler)pipeline.get(HTTP_SOCKET_TIMEOUT);
			if (timeOut != null){
				
				// 如果有，，删除该超时器
				pipeline.remove(HTTP_SOCKET_TIMEOUT);
				
			}else{
				timeOut = new ReadTimeoutHandler(time , TimeUnit.MILLISECONDS);
				pipeline.addFirst(HTTP_SOCKET_TIMEOUT , timeOut);

			}
			
			
			WriteTimeoutHandler writeOut =  (WriteTimeoutHandler)pipeline.get(HTTP_SOCKET_TIMEOUT_W);
			if (writeOut != null){
				
				// 如果有，，删除该超时器
				pipeline.remove(HTTP_SOCKET_TIMEOUT_W);
				
			}else{
				writeOut = new WriteTimeoutHandler(time , TimeUnit.MILLISECONDS);
				pipeline.addFirst(HTTP_SOCKET_TIMEOUT_W , writeOut);

			}
		}
	

	}
	
	/**
	 * 获取端口
	 * @Title: getPort
	 * @param uri
	 * @return
	 * @author xiaoa
	 */
	protected static int getPort(URI uri){
		
		int port = uri.getPort();

		if (port == -1){
			if(uri.toString().toLowerCase().startsWith("http:")){
				port = 80;
			}else{
				port = 443;
			}
		}
		
		return port;
	}



}
